import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { findDOMNode } from 'react-dom';
import { DragSource, DropTarget } from 'react-dnd';
const style = {
	border: '1px dashed gray',
	padding: '0.5rem 1rem',
	marginBottom: '.5rem',
	backgroundColor: 'white',
	cursor: 'move',
}
const cardSource = {
	beginDrag(props) {
		return {
			id: props.id,
			index: props.index,
		}
	},
}
const cardTarget = {
	hover(props, monitor, component) {
    // 拖拽元素未知的索引值
    const dragIndex = monitor.getItem().index;
    // 要放置元素位置的索引值
		const hoverIndex = props.index;
		// 移动到自己的元素上
		if (dragIndex === hoverIndex) {
			return
    }
    // 返回元素的大小及其相对于视口的位置
    const hoverBoundingRect = findDOMNode(component).getBoundingClientRect();
    // 获取元素高度的一半
    const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
    // 
		const clientOffset = monitor.getClientOffset();
    // 拖拽移动的距离
		const hoverClientY = clientOffset.y - hoverBoundingRect.top;
    // 移动的距离不超过元素高度的一半时，都不移动
		if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
			return;
		}
		if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
			return;
		}
		props.moveCard(dragIndex, hoverIndex);
		// 变化索引值
		monitor.getItem().index = hoverIndex;
	},
}
// 参数： 类型、触发的事件、注入组件的属性
@DropTarget('card', cardTarget, connect => ({
	connectDropTarget: connect.dropTarget(),
}))
@DragSource('card', cardSource, (connect, monitor) => ({
	connectDragSource: connect.dragSource(),
	isDragging: monitor.isDragging(),
}))
export default class Card extends Component {
  static propTypes = {
		connectDragSource: PropTypes.func.isRequired,
		connectDropTarget: PropTypes.func.isRequired,
		index: PropTypes.number.isRequired,
		isDragging: PropTypes.bool.isRequired,
		id: PropTypes.any.isRequired,
		text: PropTypes.string.isRequired,
		moveCard: PropTypes.func.isRequired,
	}
  render() {
    const {
			text,
			isDragging,
			connectDragSource,
			connectDropTarget,
    } = this.props;
    const opacity = isDragging ? 0 : 1;
    return connectDragSource(
			connectDropTarget(<div style={{ ...style, opacity }}>{text}</div>),
		)
  }
}

